import datetime
import json
import operator
from django.contrib.auth.hashers import make_password, check_password
from django.http import HttpResponse
from django.shortcuts import render
from django.contrib.auth import models as auth_models
from api import models as api_models
import api.forms as api_forms
from django.db.models import Q

def userlogin(request):
    '''
    用户登陆
    :param request:
    :return:
    '''
    if request.method == "POST":
        uf = api_forms.UserForm(request.POST)
        if uf.is_valid():
            username = uf.cleaned_data['account']
            password = uf.cleaned_data['password']
            try:
                remember = True if int(request.POST['remember']) == 1 else False  # uf.cleaned_data['remember']
            except:
                remember = False
            try:
                user = auth_models.User.objects.get(username=username)
                valid_password = user.password
                valid = check_password(password, valid_password)
                valid |= True if valid_password == password else False
                if valid:
                    ua_id=0
                    area = "当前用户无病区设置"
                    try:
                        ua_id = api_models.UserArea.objects.get(id=user.id).aid
                        area = api_models.Area.objects.get(id=ua_id).name
                    except Exception as e:
                        pass
                    bed_num = api_models.Bed.objects.filter(aid=ua_id).count()
                    response = HttpResponse(json.dumps({"status": 0, "id": user.id, "ward": area, "amount": bed_num,
                                                        "is_superuser": user.is_superuser}))
                    request.session["username"] = username
                    request.session["issuperuser"] = user.is_superuser
                    request.session["uid"] = user.id
                    request.session["aid"] = ua_id
                    api_models.SystemLog.objects.create(action="login", uid=user.id, action_object="system")

                    #danger code,but frontend enginer will not debug with me
                    response.set_cookie('username',username)
                    response.set_cookie('issuperuser',user.is_superuser)
                    response.set_cookie('uid',user.id)
                    response.set_cookie('aid',ua_id)
                    # response.set_cookie('sessioni',request.session['sessionid'])
                    return add_origin(response)
                else:
                    api_models.LogRuntimeInfo(uid=0, action="user password error", action_object="system")
                    return add_origin(HttpResponse(json.dumps({"status": 1001})))
            except Exception as e:
                print(e)
                return add_origin(HttpResponse(json.dumps({"status": 1002})))
        else:
            return add_origin(HttpResponse(json.dumps({"status": 1002})))
    else:
        return add_origin(HttpResponse(json.dumps({"status": 1002})))


def pulsarv_debug(request):
    response = render(request, "api/login.html")
    return add_origin(response)

def install(request):
    install_file=None
    try:
        open("INSTALL","r").close()
        return add_origin(add_origin(HttpResponse(json.dumps({"status": 1013}))))
    except Exception as e:
        open("INSTALL","w+").close()
        try:
            api_models.UserArea.objects.get(username='admin').delete()
        except:
            username = 'admin'
            password = make_password('admin', None, 'pbkdf2_sha256')
            api_models.UserArea.objects.create(is_staff=1, username=username, password=password, is_superuser=1, aid=0)
        try:
            api_models.Area.objects.get(id=0)
        except:
            api_models.Area.objects.create(name="内科病区")
        return add_origin(add_origin(HttpResponse(json.dumps({"status": 1012}))))

def userregist(request):
    '''
    用户注册
    :param request:
    :return:
    '''

    if request.method == 'POST':
        uf = api_forms.UserForm(request.POST)
        if uf.is_valid():
            username = uf.cleaned_data['account']
            password = make_password(uf.cleaned_data['password'], None, 'pbkdf2_sha256')
            try:
                user = auth_models.User.objects.get(username=username)
                return add_origin(HttpResponse(json.dumps({"status": 1003})))
            except Exception as e:
                api_models.UserArea.objects.create(username=username, password=password, is_superuser=0, aid=1)
                return add_origin(HttpResponse(json.dumps({"status": 0})))
        else:
            response = HttpResponse(json.dumps({"status": 1010}))
            return add_origin(response)
    else:
        response = HttpResponse(json.dumps({"status": 1011}))
        return add_origin(response)


def userlogout(request):
    '''
    用户注销
    :param request:
    :return:
    '''
    request.session.clear()
    response = HttpResponse(json.dumps({"status": 0}))
    response.delete_cookie('username')
    response.delete_cookie('username')
    return add_origin(response)


def mapReduce(numstr):
    try:
        return int(numstr)
    except Exception as e:
        return len(numstr)


def monitor(request, page=None, max_device=None):
    if request.session.get('uid', default=None) == None and request.COOKIES.get("uid")==None:
        return add_origin(HttpResponse(json.dumps({"status": 1009})))
    devices_data = {}
    devices_data['status'] = 0
    device_list = []
    # beds = api_models.Bed.objects.filter(aid=api_models.UserArea.objects.get(id=request.session.get("uid")).aid)
    beds = api_models.Bed.objects.filter(aid=api_models.UserArea.objects.get(id=request.COOKIES.get("uid")).aid)
    for index, bed in enumerate(beds):
        u_device = {"id": bed.bed_id,
                    "isEmpty": True,
                    "hasSignal": False,
                    "hasBattery": False,
                    "total": 0,
                    "remain": 0,
                    "speed": 0,
                    "time": datetime.datetime.now().strftime("%H:%M:%S"),
                    "remainTime": 0,
                    "alarm": 0,
                    }
        try:
            device = api_models.Devices.objects.get(bednum=bed.bed_id)
            u_device = {"id": bed.bed_id,
                        "isEmpty": False,
                        "hasSignal": True,
                        "hasBattery": True if device.battery > 0 else False,
                        "total": device.init_cap,
                        "remain": device.value_cap,
                        "speed": device.value_speed,
                        "time": device.alarm_time.strftime("%H:%M:%S"),
                        "remainTime": device.value_time,
                        "alarm": device.alarm,
                        }
        except:
            pass
        device_list.append(u_device)
    device_list = sorted(device_list, key=lambda x: mapReduce(x['id']), reverse=False)
    if page != None and max_device != None:
        devices_data['list'] = device_list[abs(page):abs(max_device)]
    else:
        devices_data['list'] = device_list
    response = HttpResponse(json.dumps(devices_data))
    return add_origin(response)


def account(request, id=None):
    '''
    GET 获取
    POST 创建
    PUT 修改
    DELETE 删除
    :param request:
    :return:
    '''
    if request.session.get('uid', default=None) == None and request.COOKIES.get("uid")==None:
        return add_origin(HttpResponse(json.dumps({"status": 1009})))
    if request.session.get('issuperuser', default=None) == False and request.COOKIES.get("issuperuser")==None:
        return add_origin(HttpResponse(json.dumps({"status": 1009})))
    if request.method == "GET":
        # uid=str(request.session.get('uid'))
        uid=str(request.COOKIES.get('uid'))
        user = auth_models.User.objects.filter(~Q(id=uid))
        res_data = {}
        res_list = []
        res_data['status'] = 0
        for index, users in enumerate(user):
            res_list.append(
                {"id": users.id, "account": users.username, "password": users.password, "desc": users.first_name})
        res_data['list'] = res_list
        return add_origin(HttpResponse(json.dumps(res_data)))
    if request.method == 'POST':
        uf = api_forms.RegisterFrom(request.POST)
        if uf.is_valid():
            username = uf.cleaned_data['account']
            password = make_password(uf.cleaned_data['password'], None, 'pbkdf2_sha256')
            try:
                user = auth_models.User.objects.get(username=username)
                return add_origin(HttpResponse(json.dumps({"status": 1003})))
            except Exception as e:
                try:
                    area=api_models.Area.objects.get(name=uf.cleaned_data['area_id'])
                    is_super=0
                    if request.POST.get("is_superuser",default=None) == 'true':
                        is_super=1
                    api_models.UserArea.objects.create(username=username, password=password, is_superuser=is_super,
                                                       first_name="",
                                                       aid=area.id)
                except:
                    return add_origin(HttpResponse(json.dumps({"status": 1006})))
                return add_origin(HttpResponse(json.dumps({"status": 0})))
        else:
            return add_origin(HttpResponse(json.dumps({"status": 1011})))
    if request.method == "PUT":
        res_data = {}
        res_data['status'] = 0
        try:
            user = auth_models.User.objects.get(id=id)
            res_data['account'] = {"id": user.id, "account": user.username, "password": user.password,
                                   "desc": user.first_name}
            user.password = request.PUT['password']
            user.save()
            response = HttpResponse(json.dumps(res_data))
        except Exception as e:
            response = HttpResponse(json.dumps({"status": 1002}))
        return add_origin(response)
    if request.method == "DELETE":
        try:
            # TODO:自身删除处理
            # if id==request.session.get('uid'):
            if id==request.COOKIES.get('uid'):
                return add_origin(HttpResponse(json.dumps({"status": 1009})))
            user=auth_models.User.objects.get(id=id)
            # TODO:根用户不可删除处理
            if user.username=='admin':
                return add_origin(HttpResponse(json.dumps({"status": 1009})))
            else:
                user.delete()
            response = HttpResponse(json.dumps({"status": 0}))
        except Exception as e:
            response = HttpResponse(json.dumps({"status": 1002}))
        return add_origin(response)


def warning(request):
    if request.session.get('uid', default=None) == None and request.COOKIES.get("uid")==None:
        return add_origin(HttpResponse(json.dumps({"status": 1009})))
    if request.method == "GET":
        try:
            page = int(request.GET['page'])
            max_device = int(request.GET['max'])
            devices = api_models.Devices.objects.all().order_by("alarm_time")[page:max_device]
        except:
            devices = api_models.Devices.objects.all().order_by("alarm_time")
        try:
            devices_data = {}
            devices_data['status'] = 0
            device_list = []
            for index, device in enumerate(devices):
                if device.bednum != "-1" and device.alarm != 0:
                    try:
                        # api_models.Bed.objects.get(id=request.session.get('aid'),bed_id=device.bednum)
                        api_models.Bed.objects.get(id=request.COOKIES.get('aid'),bed_id=device.bednum)
                        continue
                    except:
                        device_list.append({"id": device.bednum,
                                            "isEmpty": False if device.value_cap == 0 else True,
                                            "hasSignal": True,
                                            "hasBattery": False if device.battery == 0 else True,
                                            "total": device.init_cap,
                                            "alarm": device.alarm,
                                            "remain": device.value_cap,
                                            "speed": device.value_speed,
                                            "time": device.alarm_time.strftime("%H:%M:%S"),
                                            "remainTime": device.value_time,
                                            })
                    pass
            devices_data['list'] = device_list
        except Exception as e:
            api_models.LogRuntimeInfo(uid=0, action=("get warring monitor %s" % e), action_object="system")
            return add_origin(HttpResponse(json.dumps({"status": 1008})))
        return add_origin(HttpResponse(json.dumps(devices_data)))


def bunk(request, id=None):
    '''
    床位处理
    :param request:
    :param id:
    :return:
    '''
    if request.session.get('uid', default=None) == None and request.COOKIES.get("uid")==None:
        return add_origin(HttpResponse(json.dumps({"status": 1009})))
    if request.method == "GET":
        res_data = {}
        res_list = []
        res_data['status'] = 0
        try:
            # beds = api_models.Bed.objects.filter(aid=request.session.get('aid'))
            beds = api_models.Bed.objects.filter(aid=request.COOKIES.get('aid'))
            for bed in beds:
                res_list.append({"id": bed.id, "number": bed.bed_id, "desc": bed.desc})
            res_data['list'] = res_list
            response = HttpResponse(json.dumps(res_data))
        except Exception as e:
            # api_models.LogRuntimeInfo(uid=request.session.get("uid",default=0), action=("get warring bunk %s" % e), action_object="system")
            api_models.LogRuntimeInfo(uid=request.COOKIES.get("uid",default=0), action=("get warring bunk %s" % e), action_object="system")
            response = HttpResponse(json.dumps({"status": 1004}))
        return add_origin(response)
    if request.method == "POST":
        try:
            # bed = api_models.Bed.objects.get(aid=request.session.get('aid'), bed_id=request.POST['number'])
            bed = api_models.Bed.objects.get(aid=request.COOKIES.get('aid'), bed_id=request.POST['number'])
            return add_origin(HttpResponse(json.dumps({"status": 1005})))
        except Exception as e:
            api_models.LogRuntimeInfo(uid=0, action=("get warring monitor %s" % e), action_object="system")
            # api_models.Bed.objects.create(aid=request.session.get('aid'), bed_id=request.POST['number'])
            api_models.Bed.objects.create(aid=request.COOKIES.get('aid'), bed_id=request.POST['number'])
            return add_origin(HttpResponse(json.dumps({"status": 0})))
    if request.method == "DELETE":
        try:
            # api_models.Bed.objects.get(id=id, aid=request.session.get('aid')).delete()
            api_models.Bed.objects.get(id=id, aid=request.COOKIES.get('aid')).delete()
            return add_origin(HttpResponse(json.dumps({"status": 0})))
        except Exception as e:
            # api_models.LogRuntimeInfo(uid=request.session.get("uid",default=0), action=("get warring bunk %s" % e), action_object="system")
            api_models.LogRuntimeInfo(uid=request.COOKIES.get("uid",default=0), action=("get warring bunk %s" % e), action_object="system")
            return add_origin(HttpResponse(json.dumps({"status": 1010})))
    if request.method == "PUT":
        try:
            try:
                # api_models.Bed.objects.get(aid=request.session.get('aid'), bed_id=request.PUT['number'])
                api_models.Bed.objects.get(aid=request.COOKIES.get('aid'), bed_id=request.PUT['number'])
                return add_origin(HttpResponse(json.dumps({"status": 1005})))
            except:
                # bed = api_models.Bed.objects.get(id=id, aid=request.session.get('aid'))
                bed = api_models.Bed.objects.get(id=id, aid=request.COOKIES.get('aid'))
                bed.bed_id = request.PUT['number']
                bed.save()
            return add_origin(HttpResponse(json.dumps({"status": 0})))
        except Exception as e:
            # api_models.LogRuntimeInfo(uid=request.session.get("uid",default=0), action=("get warring bunk %s" % e), action_object="system")
            api_models.LogRuntimeInfo(uid=request.COOKIES.get("uid"), action=("get warring bunk %s" % e), action_object="system")
            return add_origin(HttpResponse(json.dumps({"status": 1010})))


def add_origin(response):
    '''
    消息头打包
    :param response:
    :return:
    '''
    response['Access-Control-Allow-Origin'] = "http://localhost:9080"
    response['Access-Control-Allow-Credentials'] = "True"
    response['Access-Control-Allow-Methods'] = "DELETE,PUT,POST,GET"
    return response


def area(request, name=None):
    if request.session.get('uid', default=None) == None and request.COOKIES.get("uid")==None:
        return add_origin(HttpResponse(json.dumps({"status": 1009})))
    # if request.session.get('issuperuser'):
    if request.COOKIES.get('issuperuser'):
        if request.method == "GET":
            res_data = {}
            res_list = []
            res_data['status'] = 0
            try:
                areas = api_models.Area.objects.order_by("id").all()
                for area in areas:
                    res_list.append({"id": area.id, "number": area.name})
                res_data['list'] = res_list
                response = HttpResponse(json.dumps(res_data))
            except Exception as e:
                # api_models.LogRuntimeInfo(uid=request.session.get("uid", default=0), action=("get warring area %s" % e),action_object="system")
                api_models.LogRuntimeInfo(uid=request.COOKIES.get("uid"), action=("get warring area %s" % e),action_object="system")
                response = HttpResponse(json.dumps({"status": 1015}))
            return add_origin(response)
        if request.method == "POST":
            try:
                area = api_models.Area.objects.get(name=request.POST['name'])
                response = HttpResponse(json.dumps({"status": 1014}))
                return add_origin(response)
            except:
                api_models.Area.objects.create(name=request.POST['name'])
                return add_origin(HttpResponse(json.dumps({"status": 0})))
        if request.method == "DELETE":
            try:
                api_models.Area.objects.get(name=name).delete()
                return add_origin(HttpResponse(json.dumps({"status": 0})))
            except Exception as e:
                # api_models.LogRuntimeInfo(uid=request.session.get("uid", default=0), action=("get warring area %s" % e),action_object="system")
                api_models.LogRuntimeInfo(uid=request.COOKIES.get("uid", default=0), action=("get warring area %s" % e),action_object="system")
                return add_origin(HttpResponse(json.dumps({"status": 1006})))